home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-15 | 6.7 KB | 192 lines | [TEXT/CCL2] |
- ;-*- Mode: Lisp; Package: CCL -*-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; faster-make-instance-patch.lisp
- ;;copyright © 1992, 1993, Apple Computer, Inc.
- ;;
- ;;
- ;; Speed up make-instance by 228 microseconds (on a ci)
-
- ; (require-type class 'std-class) used to call find-class
- ; Speed up (make-instance 'class-name ...) by an additional
- ; 240 microseconds by doing the gethash at load time.
-
- ; Files compiled after this patch has been loaded
- ; will fail to load in versions of MCL 2.0 that do not
- ; include it; attempting this will cause "Error:
- ; Undefined function CCL::FIND-CLASS-CELL." If you produce
- ; software that may be loaded into an MCL 2.0 without this
- ; patch, you may wish to include this source with your code.
-
-
- (in-package :ccl)
-
- (eval-when (:compile-toplevel :execute)
- (require :lapmacros))
-
- (let ((*warn-if-redefine* nil)
- (*warn-if-redefine-kernel* nil))
-
- (eval-when (:compile-toplevel :execute :load-toplevel)
- (set-type-predicate 'std-class 'std-class-p))
-
- (defun default-initargs (class initargs)
- (unless (std-class-p class)
- (setq class (require-type class 'std-class)))
- (when (null (%class-cpl class)) (initialize-class class))
- (let ((defaults ()))
- (dolist (key.form (%class-default-initargs class))
- (unless (pl-search initargs (%car key.form))
- (setq defaults
- (list* (if (listp (%cdr key.form))
- (%cadr key.form)
- (funcall (%cdr key.form)))
- (%car key.form)
- defaults))))
- (when defaults
- (setq initargs (append initargs (nreverse defaults))))
- initargs))
-
- (defun find-class-cell (name create?)
- (let ((cell (gethash name %find-classes%)))
- (or cell
- (and create?
- (setf (gethash name %find-classes%) (cons name nil))))))
-
- (without-interrupts
- (defun find-class (name &optional (errorp t) environment)
- (let* ((cell (find-class-cell name nil)))
- (declare (list cell))
- (or (cdr cell)
- (let ((defenv (and environment (definition-environment environment))))
- (when defenv
- (dolist (class (defenv.classes defenv))
- (when (eq name (%class-name class))
- (return class)))))
- (when (or errorp (not (symbolp name)))
- (error "Class named ~S not found." name)))))
-
- ; Update %find-classes% to the new order
- (maphash #'(lambda (name class)
- (unless (listp class)
- (setf (gethash name %find-classes%) (cons name class))))
- %find-classes%)
-
- (defun set-find-class (name class)
- (setq name (require-type name 'symbol))
- (let ((cell (find-class-cell name class)))
- (declare (type list cell))
- (when *warn-if-redefine-kernel*
- (let ((old-class (cdr cell)))
- (when (and old-class (neq class old-class) (%class-kernel-p old-class))
- (cerror "Redefine ~S."
- "~S is already defined in the CCL kernel." old-class)
- (setf (%class-kernel-p old-class) nil))))
- (when (null class)
- (when cell
- (setf (cdr cell) nil))
- (return-from set-find-class nil))
- (setq class (require-type class 'class))
- (when (built-in-type-p name)
- (unless (eq (cdr cell) class)
- (error "Cannot redefine built-in type name ~S" name)))
- (when (%deftype-expander name)
- (cerror "set ~S anyway, removing the ~*~S definition"
- "Cannot set ~S because type ~S is already defined by ~S"
- `(find-class ',name) name 'deftype)
- (%deftype name nil nil))
- (setf (cdr cell) class)))
-
- ) ; end of without-interrupts
-
- (defun map-classes (function)
- (with-hash-table-iterator (m %find-classes%)
- (loop
- (multiple-value-bind (found name cell) (m)
- (declare (list cell))
- (unless found (return))
- (when (cdr cell)
- (funcall function name (cdr cell)))))))
-
- (defun clear-specializer-direct-methods-caches ()
- (setq *maintain-class-direct-methods* nil)
- (map-classes #'(lambda (name class)
- (declare (ignore name))
- (when (typep class 'class)
- (setf (%class-direct-methods class) nil)))))
-
- (defun clear-valid-initargs-caches ()
- (map-classes #'(lambda (name class)
- (declare (ignore name))
- (when (std-class-p class)
- (setf (%class-make-instance-initargs class) nil
- (%class-reinit-initargs class) nil
- (%class-redefined-initargs class) nil
- (%class-changed-initargs class) nil
- (%class-aux-init-functions-cache class) nil)))))
-
- #|
- (defun %make-instance (class-cell &rest initargs)
- (declare (dynamic-extent initargs))
- (apply #'make-instance
- (or (cdr class-cell) (car (the list class-cell)))
- initargs))
- |#
-
- ; This saves 29 microseconds on a ci.
- ; I really wish the compiler would special case rest args
- ; that are used only as the last argument to apply.
- (defun %make-instance (&lap class-cell &rest initargs)
- (lap
- (if# (eq (cmp.w ($ 8) nargs))
- ; 2 args. class-cell is in arg_y
- (move.l arg_y atemp0)
- (bif (eq (dtagp arg_y $t_cons)) @bad)
- (move.l (cdr atemp0) arg_y)
- (bif (ne (cmp.l nilreg arg_y)) @doit)
- (move.l (car atemp0) arg_y)
- elseif# mi
- (if# (eq (tst.w nargs))
- ; no args, generate error
- (jsr_subprim $sp-n-req-rest)
- (dc.w 4)
- (dc.w #_debugger))
- ; 1 arg. class-cell is in arg_z
- (move.l arg_z atemp0)
- (bif (eq (dtagp arg_z $t_cons)) @bad)
- (move.l (cdr atemp0) arg_z)
- (bif (ne (cmp.l nilreg arg_z)) @doit)
- (move.l (car atemp0) arg_z)
- elseif# (eq (cmp.w ($ 12) nargs))
- ; 3 args. class-cell is in arg_x
- (move.l arg_x atemp0)
- (bif (eq (dtagp arg_x $t_cons)) @bad)
- (move.l (cdr atemp0) arg_x)
- (bif (ne (cmp.l nilreg arg_x)) @doit)
- (move.l (car atemp0) arg_x)
- else#
- ; > 3 args. class-cell is on the stack
- (lea (vsp nargs -16) atemp1)
- (move.l @atemp1 da)
- (move.l da atemp0)
- (bif (eq (dtagp da $t_cons)) @bad)
- (move.l (cdr atemp0) da)
- (if# (ne (cmp.l nilreg da))
- (move.l da @atemp1)
- (bra @doit))
- (move.l (car atemp0) @atemp1))
- @doit
- (jmp #'make-instance)
- @bad
- (vpush_argregs_nz)
- (pea (vsp nargs))
- (wtaerr atemp0 'list)))
-
- (define-compiler-macro make-instance (&whole call class &rest initargs)
- (if (and (listp class)
- (eq (car class) 'quote)
- (symbolp (cadr class))
- (null (cddr class)))
- `(%make-instance (load-time-value (find-class-cell ,class t))
- ,@initargs)
- call))
- )